#ifndef __CONNECT_POOL_H__
#define __CONNECT_POOL_H__

#include "mysqlDataBase.h"
/* 智能指针 */
#include <memory>
/* 容器队列 */
#include <queue>

#include <string>
#include <fstream>
#include <iostream>
#include <jsoncpp/json/json.h>
/* 锁 */
#include <mutex>
/* 条件变量 */
#include <condition_variable>
/* 线程类 */
#include <thread>

class ConnectPool
{
public:
    /* 提供一个静态方法，让外部调用唯一实例 */
    static ConnectPool *getConnectPool();
    /* 删除拷贝构造 */
    ConnectPool(const ConnectPool *obj) = delete;
    /* 删除赋值 */
    ConnectPool &operator=(const ConnectPool *obj) = delete;
    /* 析构函数 */
    ~ConnectPool();

public:
    /* 从连接池中取出一个MySql连接 */
    std::shared_ptr<MysqlDataBase> getConnection();

private:
    /* 构造函数私有化 */
    ConnectPool();
    /* 添加连接到连接池中 */
    bool addConnection();

    /* 生产者线程入口 - 向数据库连接池生产连接句柄 */
    void produceConnection();

    /* 回收线程入口 - 回收数据库连接池的连接 */
    void recycleConnection();

    /* 解析配置文件 */
    bool parseConfigFile(const std::string &path);

private:
    /* 连接池内部维护的数据库连接句柄 */
    std::queue<MysqlDataBase *> m_connectQueue;
    /* 维护锁 */
    std::mutex m_mutex;
    /* 条件变量 */
    std::condition_variable m_cond_produce; /* 生产者条件变量 - 连接池连接不够的时候 */
    std::condition_variable m_cond_consume; /* 消费者条件变量 - 连接池有多余连接的时候 */

    /* 配置文件的私有属性 */
    std::string m_hostname;
    std::string m_username;
    std::string m_passwd;
    int m_port;
    std::string m_dbname;
    int m_minSize;
    int m_maxSize;

    int m_maxIdleTime;
};

#endif // __CONNECT_POOL_H__